

/***
 * @Date            : 2024-08-12 23:52:55
 * @Author          : AnimateX(Baron)
 * @LastEditors     : AnimateX(Baron)
 * @LastEditTime    : 2024-08-12 23:52:59
 * @FilePath        : /src/p15.cpp
 * @CopyRight       : Copyright (c) 2024 RockChip Technology Co. Ltd. All rights reserved.
 * @Description     :
 */
#include "p8.h"
#include "p15.h"
#include <ios>
#include <iostream>
#include <string_view>
#include "timer.h"




namespace HOMEWORK_P15 {
    // Description: 将每个成员函数都使用引用返回实例对象，这样就可以连续使用 '.' 链接下一个成员函数
    void testThisPtr() {
        Calc calc {};
        /**
         * First, calc.add(5) is called, which adds 5 to m_value.
         * add() then returns a reference to *this, which is a reference to implicit object calc,
         * so calc will be the object used in the subsequent evaluation.
         * Next calc.sub(3) evaluates, which subtracts 3 from m_value and again returns calc.
         * Finally, calc.mult(4) multiplies m_value by 4 and returns calc, which isn’t used further,
         * and is thus ignored.
         */
        calc.add(5).sub(3).mult(4);
        std::cout << calc.getValue() << '\n';

        Simple simple{1};
        simple.setId(2);
        simple.print();
    }

    void testResetThisInstance() {
        Calc calc{};
        calc.add(5).sub(3).mult(4);

        std::cout << calc.getValue() << '\n'; // prints 8

        calc.reset();

        std::cout << calc.getValue() << '\n'; // prints 0
    }

    void test_chap_15_3() {
        Fruit apple { FruitType::apple };

        if (apple.getType() == FruitType::apple)
            std::cout << " I'm an apple." << '\n';
        else
            std::cout << " I'm not an apple." << '\n';

        FruitNew cherry { FruitNew::cherry };
        if (cherry.getType() == FruitNew::Type::cherry)
            std::cout << " I'm a cherry." << '\n';
        else
            std::cout << " I'm not a cherry." << '\n';

        Empployee john { "john", 250, 200000.0 };
        Empployee::Printer p{};
        Empployee::IDType id = john.getId();
        std::string_view name = john.getName();
        p.print(john);

        std::cout << " John info, name: " << name << ", id: " << id << '\n';
    }

    void test_chap_15_4() {
        NetWorkData test_n("hahaha");
        test_n.addData("Hi, sb");
        test_n.addData("shit is you.");
        test_n.addData("So lucky.");
    }

    void test_chap_15_5() {
        Pair p1 {5, 6};
        std::cout << std::boolalpha << "isEqual(5, 6): " << p1.isEqual( Pair<int> {5, 6}) << '\n';
        std::cout << std::boolalpha << "isEqual(5, 7): " << p1.isEqual( Pair{5, 7}) << '\n';

        Triad<int, int, int> t1{1, 2, 3};
        t1.print();
        std::cout << '\n';
        std::cout << t1.getFirst() << '\n';

        using namespace std::literals::string_literals;
        const Triad<int, double, std::string> t2 { 1, 2.3, "Hello"s };
        t2.print();
        std::cout << '\n';
    }

    void test_chap_15_6() {
        Something some_a {};
        Something some_b {};
        Something some_c {};

        std::cout << "Test: " << Something::s_value << '\n';

        some_a.print();
        some_b.print();
        some_c.print();
    }

    void test_chap_15_7() {
        for (int count{ 1 }; count <= 10; ++count ) {
            std::cout << Random::get(1, 6) << '\t';
        }

        std::cout << '\n';
    }

    void printWeather(const Temperature& temperature, const Humidity& humidity) {
        std::cout << "The temperature is " << temperature.m_temp << " and the humidity is " << humidity.m_humidity << '\n';
    }

    void test_chap_15_8() {
        Accumulator acc{};
        acc.add(5);

        // 友元函数
        print(acc);

        Humidity humidity{12};
        Temperature temperature {37};

        printWeather(temperature, humidity);
    }

    void DisplayNew::displayStorageNew(const StorageNew& storage) {
        if (m_displayIntFirst) {
            std::cout << storage.m_nValue << ' ' << storage.m_dValue << '\n';
        } else {
            std::cout << storage.m_dValue << ' ' << storage.m_nValue << '\n';
        }
    }

    void test_chap_15_9() {
#if 0
        Storage storage {2, 2.3};
        Display display {true};

        display.displayStorage(storage);
        display.setDisplayIntFirst(false);
        display.displayStorage(storage);
#else
        StorageNew storage {2, 2.3};
        DisplayNew display {true};

        display.displayStorageNew(storage);
        display.setDisplayIntFirst(false);
        display.displayStorageNew(storage);
#endif
    }

    void test_chap_15_9_homework() {
        Timer timer;
        timer.start();

        Vector3d vec {2, 3, 4};
        Point3d ptx {1, 2, 3};

        vec.print();
        ptx.print();
        ptx.moveByVector(vec);
        ptx.print();

        long long duration = timer.elapsedMilliseconds(); // 获取经过的时间
        std::cout << "Duration: " << duration << " milliseconds" << std::endl;
    }
}


namespace HOMEWORK_P15_9_2 {
    void Point3d::moveByVector(const Vector3d& v) {
        m_pt_x += v.m_pt_x;
        m_pt_y += v.m_pt_y;
        m_pt_z += v.m_pt_z;
    }

    void test_chap_15_9_homework() {
        Timer timer;
        timer.start();

        Vector3d vec {2, 3, 4};
        Point3d ptx {1, 2, 3};

        vec.print();
        ptx.print();
        ptx.moveByVector(vec);
        ptx.print();

        long long duration = timer.elapsedMilliseconds(); // 获取经过的时间
        std::cout << "Duration: " << duration << " milliseconds" << std::endl;
    }

}


namespace HOMEWORK_P15_10 {

    Employee createEmployee(std::string_view name) {
        Employee e {name};

        return e;
    }

    void test_reference() {
        Employee joe { "Joe" };
        std::cout << joe.getName() << '\n';

        std::cout << createEmployee("Frank").getName() << '\n';
    }
}


namespace HOMEWORK_P15_SUMMARY_TEST {

    void Monster::print() {
        std::string_view typeName = getTypeString();
        if (m_numHitPoint == 0) {
            std::cout << typeName << " the " << m_name << " is dead.\n";
        } else {
            std::cout << typeName << " the " << m_name << " has " << m_numHitPoint << " hit points and says " << m_roar << ".\n";
        }
    }

    Monster Monster::generate() {
        return Monster {Monster::Skeleton, "Bones", "*rattle*", 4};

    }

    namespace MonsterGenerator {
        const std::string getName(int n) {
            switch (n) {
                case 0:  return "Blarg";
                case 1:  return "Moog";
                case 2:  return "Pksh";
                case 3:  return "Tyrn";
                case 4:  return "Mort";
                case 5:  return "Hans";
                default: return "???";
            }
        }

        const std::string getRoar(int n) {
            switch (n) {
                case 0:  return "*ROAR*";
                case 1:  return "*peep*";
                case 2:  return "*squeal*";
                case 3:  return "*whine*";
                case 4:  return "*growl*";
                case 5:  return "*burp*";
                default: return "???";
            }
        }

        Monster generator() {
            return Monster {
                static_cast<Monster::Type>(Random::get(0, Monster::maxMonsterTypes - 1)),
                getName(Random::get(0, 5)),
                getRoar(Random::get(0, 5)),
                Random::get(1, 100)
                };
        }
    }

    void test() {
        Monster skeleton{ Monster::Skeleton, "Bones", "*rattle*", 4 };
        skeleton.print();

        Monster vampire{ Monster::Vampire, "Nibblez", "*hiss*", 0 };
        vampire.print();

        Monster m{ MonsterGenerator::generator() };
        m.print();
    }
}
